package com.mhc.suzuki.controller;

import com.mhc.haval.api.service.IStaffRoleService;
import com.mhc.haval.security.model.User;
import com.mhc.suzuki.api.model.DataDictDTO;
import com.mhc.suzuki.api.service.IDataDictService;
import com.mhc.suzuki.bo.*;
import com.mhc.suzuki.constant.DepartmentEnum;
import com.mhc.suzuki.constant.ErrorCodeEnum;
import com.mhc.suzuki.constant.RepayStatusEnum;
import com.mhc.suzuki.dal.query.DataDictQuery;
import com.mhc.suzuki.dal.query.OrderQuery;
import com.mhc.suzuki.dal.query.OverdueListQuery;
import com.mhc.suzuki.form.*;
import com.mhc.suzuki.service.OverdueService;
import com.mhc.suzuki.util.BeanCopierUtil;
import com.mhc.suzuki.vo.DebtCollectDetailVO;
import com.mhc.suzuki.vo.DebtCollectHisVO;
import com.mhc.suzuki.vo.LawsuitHisVO;
import com.mhc.suzuki.vo.TowingHisVO;
import com.subaru.common.entity.BizResult;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

/**
 * @author Churry
 * @create 2017-08-25 11:45
 **/
@Slf4j
@RestController
@RequestMapping("/overdue")
public class OverdueController {

    @Autowired
    OverdueService overdueService;
    @Autowired
    IDataDictService dataDictService;
    @Autowired
    IStaffRoleService staffRoleService;

    /**
     * 查询逾期清单列表，查询条件可以有客户姓名，客户身份证号，银行名称
     *
     * @param overdueListQueryForm 查询条件
     * @return
     */
    @ApiOperation(value = "查询逾期清单列表", notes = "查询逾期清单列表，查询条件可以有客户姓名，客户身份证号，银行名称")
    @ApiImplicitParam(name = "overdueListQueryForm", value = "逾期清单列表查询条件", required = false, dataType = "OverdueListQueryForm")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public Object getOverdueList(OverdueListQueryForm overdueListQueryForm) {
        BizResult bizResult;
        try {
            OverdueListQuery overdueListQuery = new OverdueListQuery();
            Optional<OverdueListQueryForm> overdueListQueryFormOptional = Optional.ofNullable(overdueListQueryForm);
            //判断查询条件是否为空
            if (overdueListQueryFormOptional.isPresent()) {
                String queryCondition = overdueListQueryForm.getQueryCondition();
                Optional<String> queryConditionOptional = Optional.ofNullable(queryCondition);
                if (queryConditionOptional.isPresent() && !"".equals(queryConditionOptional.get())) {
                    overdueListQuery.or().andCustomerNameEqualTo(queryCondition).andStatusNotEqualTo(RepayStatusEnum.DELETED.getCode());
                    overdueListQuery.or().andCustomerIdCardEqualTo(queryCondition).andStatusNotEqualTo(RepayStatusEnum.DELETED.getCode());
                    overdueListQuery.or().andBankNameEqualTo(queryCondition).andStatusNotEqualTo(RepayStatusEnum.DELETED.getCode());
                }else {
                    overdueListQuery.createCriteria().andStatusNotEqualTo(RepayStatusEnum.DELETED.getCode());
                }
                overdueListQuery.setPageNo(overdueListQueryForm.getPageNo());
                overdueListQuery.setPageSize(overdueListQueryForm.getPageSize());
            }
            bizResult = BizResult.create(overdueService.getOverdueList(overdueListQuery), true, ErrorCodeEnum.SUCCESS.getErrCode(), ErrorCodeEnum.SUCCESS.getErrMsg());
            bizResult.setTotalCount(overdueService.getCountByQuery(overdueListQuery));
            bizResult.setPageNo(overdueListQuery.getPageNo());
            bizResult.setPageSize(overdueListQuery.getPageSize());
            return bizResult;
        } catch (Exception e) {
            log.error("ERROR IN getOverdueList", e);
            return BizResult.create(ErrorCodeEnum.SYS_ERROR.getErrCode(), e.getMessage());
        }
    }

    /**
     * 查询逾期记录-催收详情信息，如果订单只有一条则返回详细信息，如果订单有多条，则返回对应的订单列表
     *
     * @param overdueId
     * @return
     */
    @ApiOperation(value = "查询逾期记录-催收详情信息", notes = "查询逾期记录-催收详情信息，如果订单只有一条则返回详细信息，如果订单有多条，则返回对应的订单列表")
    @ApiImplicitParam(name = "overdueId", value = "逾期记录编号", required = true, paramType = "path", dataType = "Long")
    @RequestMapping(value = "/detail/{overdueId}", method = RequestMethod.GET)
    public Object getDebtCollectDetail(@PathVariable Long overdueId) {
        try {
            List<String> orderNoList = overdueService.getOrderNoByOverdueId(overdueId);
            if (orderNoList.size() == 1) {
                BizResult result = BizResult.create(this.getDebtCollectDetailByOrderNo(orderNoList.get(0)), true, ErrorCodeEnum.SUCCESS.getErrCode(), ErrorCodeEnum.SUCCESS.getErrMsg());
                result.setTotalCount(orderNoList.size());
                return result;
            }
            //返回的订单编号不止一条，交由工作人员判断逾期记录归属于哪条订单
            else if (orderNoList.size() > 1) {
                OrderQuery orderQuery = new OrderQuery();
                for (String orderNo : orderNoList) {
                    orderQuery.or().andOrderNoEqualTo(orderNo);
                }
                BizResult result = BizResult.create(overdueService.getOverdueOrderList(orderQuery), true, ErrorCodeEnum.SUCCESS.getErrCode(), ErrorCodeEnum.SUCCESS.getErrMsg());
                result.setTotalCount(orderNoList.size());
                return result;
            }
            return BizResult.create(ErrorCodeEnum.SYS_ERROR.getErrCode(), ErrorCodeEnum.SYS_ERROR.getErrMsg());
        } catch (Exception e) {
            log.error("ERROR IN getDebtCollectDetail", e);
            return BizResult.create(ErrorCodeEnum.SYS_ERROR.getErrCode(), e.getMessage());
        }
    }

    /**
     * 根据订单编号，查询逾期记录-催收详情信息
     *
     * @param orderNo
     * @return
     */
    @ApiOperation(value = "查询逾期记录-催收详情信息", notes = "根据订单编号，查询逾期记录-催收详情信息")
    @ApiImplicitParam(name = "orderNo", value = "订单编号", required = true, paramType = "path", dataType = "String")
    @RequestMapping(value = "/detail/order/{orderNo}", method = RequestMethod.GET)
    public Object getDebtCollectDetailByOrderNo(@PathVariable String orderNo) {
        try {
            DebtCollectDetailBO debtCollectDetailBO = overdueService.getDebtCollectDetail(orderNo);
            //令人犯晕的模型转换
            DebtCollectDetailVO debtCollectDetailVO = BeanCopierUtil.convert(debtCollectDetailBO, DebtCollectDetailVO.class);
            List<DebtCollectHisVO> callingDebtList = new ArrayList<>();
            List<DebtCollectHisVO> visitDebtList = new ArrayList<>();
            List<TowingHisVO> towingHisList = new ArrayList<>();
            List<LawsuitHisVO> lawsuitHisList = new ArrayList<>();
            for (DebtCollectHisBO debtCollectHisBO : debtCollectDetailBO.getCallingDebtList()) {
                DebtCollectHisVO debtCollectHisVO = BeanCopierUtil.convert(debtCollectHisBO, DebtCollectHisVO.class);
                callingDebtList.add(debtCollectHisVO);
            }
            for (DebtCollectHisBO debtCollectHisBO : debtCollectDetailBO.getVisitDebtList()) {
                DebtCollectHisVO debtCollectHisVO = BeanCopierUtil.convert(debtCollectHisBO, DebtCollectHisVO.class);
                visitDebtList.add(debtCollectHisVO);
            }
            for (TowingHisBO towingHisBO : debtCollectDetailBO.getTowingHisList()) {
                TowingHisVO towingHisVO = BeanCopierUtil.convert(towingHisBO, TowingHisVO.class);
                towingHisList.add(towingHisVO);
            }
            for (LawsuitHisBO lawsuitHisBO : debtCollectDetailBO.getLawsuitHisList()) {
                LawsuitHisVO lawsuitHisVO = BeanCopierUtil.convert(lawsuitHisBO, LawsuitHisVO.class);
                lawsuitHisList.add(lawsuitHisVO);
            }
            debtCollectDetailVO.setCallingDebtList(callingDebtList);
            debtCollectDetailVO.setVisitDebtList(visitDebtList);
            debtCollectDetailVO.setTowingHisList(towingHisList);
            debtCollectDetailVO.setLawsuitHisList(lawsuitHisList);
            return BizResult.create(debtCollectDetailVO, true, ErrorCodeEnum.SUCCESS.getErrCode(), ErrorCodeEnum.SUCCESS.getErrMsg());
        } catch (Exception e) {
            log.error("ERROR IN getDebtCollectDetailByOrderNo", e);
            return BizResult.create(ErrorCodeEnum.SYS_ERROR.getErrCode(), e.getMessage());
        }
    }

    /**
     * 获取资产保全部外勤的催收待办列表
     * @param logedUser
     * @return
     */
    @ApiOperation(value = "获取资产保全部外勤的催收待办列表", notes = "获取资产保全部外勤的催收待办列表")
    @RequestMapping(value = "/collect/task/list", method = RequestMethod.GET)
    public Object getOutWorkerTaskList(@AuthenticationPrincipal User logedUser, String keyword) {
        Optional<User> userOptional = Optional.ofNullable(logedUser);
        if (userOptional.isPresent()) {
            try {
                Map<String, Object> queryMap = new HashMap<>(64);
                queryMap.put("staffId", logedUser.getStaffId());
                if (keyword != null && !"".equals(keyword) && !"null".equals(keyword)) {
                    queryMap.put("keyword", keyword);
                }
                BizResult result = BizResult.create(overdueService.getOutWorkerTaskList(queryMap), true, ErrorCodeEnum.SUCCESS.getErrCode(), ErrorCodeEnum.SUCCESS.getErrMsg());
                result.setTotalCount(((List)result.getData()).size());
                return result;
            } catch (Exception e) {
                log.error("ERROR IN getOutWorkerTaskList", e);
                return BizResult.create(ErrorCodeEnum.SYS_ERROR.getErrCode(), e.getMessage());
            }
        } else {
            return BizResult.create(ErrorCodeEnum.NOT_LOGIN.getErrCode(), ErrorCodeEnum.NOT_LOGIN.getErrMsg());
        }
    }

    /**
     * 上传excel文件，导入逾期清单
     *
     * @param overdueListFiles 逾期清单文件
     * @return
     */
    @ApiOperation(value = "上传逾期清单文件", notes = "上传excel文件，导入逾期清单")
    @ApiImplicitParam(name = "overdueListFiles", value = "逾期清单文件", required = true, paramType = "body", dataType = "List<MultipartFile>")
    @RequestMapping(value = "/list/upload", method = RequestMethod.POST)
    public Object uploadOverdueList(@AuthenticationPrincipal User logedUser, @RequestParam("file") List<MultipartFile> overdueListFiles) {
        Optional<User> userOptional = Optional.ofNullable(logedUser);
        if (userOptional.isPresent()) {
            return BizResult.create(overdueService.uploadOverdueList(logedUser.getStaffId(), overdueListFiles), Boolean.TRUE, ErrorCodeEnum.SUCCESS.getErrCode(), ErrorCodeEnum.SUCCESS.getErrMsg());
        } else {
            return BizResult.create(ErrorCodeEnum.NOT_LOGIN.getErrCode(), ErrorCodeEnum.NOT_LOGIN.getErrMsg());
        }
    }

    /**
     * 新增电催记录
     *
     * @param debtCollectHisForm
     * @return
     */
    @ApiOperation(value = "新增电催记录", notes = "新增电催记录")
    @ApiImplicitParam(name = "debtCollectHisForm", value = "电催记录表单", required = true, paramType = "body", dataType = "DebtCollectHisForm")
    @RequestMapping(value = "/detail/callingdebt", method = RequestMethod.POST)
    public Object addCallingDebtRecord(@AuthenticationPrincipal User logedUser, @RequestBody DebtCollectHisForm debtCollectHisForm) {
        Optional<User> userOptional = Optional.ofNullable(logedUser);
        if (userOptional.isPresent()) {
            try {
                DebtCollectHisBO debtCollectHisBO = BeanCopierUtil.convert(debtCollectHisForm, DebtCollectHisBO.class);
                return BizResult.create(null, overdueService.addCallingDebtRecord(logedUser.getStaffId(), debtCollectHisBO), ErrorCodeEnum.SUCCESS.getErrCode(), ErrorCodeEnum.SUCCESS.getErrMsg());
            } catch (Exception e) {
                log.error("ERROR IN addCallingDebtRecord", e);
                return BizResult.create(ErrorCodeEnum.SYS_ERROR.getErrCode(), e.getMessage());
            }
        } else {
            return BizResult.create(ErrorCodeEnum.NOT_LOGIN.getErrCode(), ErrorCodeEnum.NOT_LOGIN.getErrMsg());
        }
    }

    /**
     * 新增上门催收记录
     *
     * @param debtCollectHisForm
     * @return
     */
    @ApiOperation(value = "新增上门催收记录", notes = "新增上门催收记录")
    @ApiImplicitParam(name = "debtCollectHisForm", value = "电催记录表单", required = true, paramType = "body", dataType = "DebtCollectHisForm")
    @RequestMapping(value = "/detail/visitdebt", method = RequestMethod.POST)
    public Object addVisitDebtRecord(@AuthenticationPrincipal User logedUser, @RequestBody DebtCollectHisForm debtCollectHisForm) {
        Optional<User> userOptional = Optional.ofNullable(logedUser);
        if (userOptional.isPresent()) {
            try {
                DebtCollectHisBO debtCollectHisBO = BeanCopierUtil.convert(debtCollectHisForm, DebtCollectHisBO.class);
                return BizResult.create(null, overdueService.addVisitDebtRecord(logedUser.getStaffId(), debtCollectHisBO), ErrorCodeEnum.SUCCESS.getErrCode(), ErrorCodeEnum.SUCCESS.getErrMsg());
            } catch (Exception e) {
                log.error("ERROR IN addVisitDebtRecord", e);
                return BizResult.create(ErrorCodeEnum.SYS_ERROR.getErrCode(), e.getMessage());
            }
        } else {
            return BizResult.create(ErrorCodeEnum.NOT_LOGIN.getErrCode(), ErrorCodeEnum.NOT_LOGIN.getErrMsg());
        }
    }

    /**
     * 新增拖车记录，修改拖车记录（录入取车时间）
     *
     * @param logedUser
     * @param towingRecordForm
     * @return
     */
    @ApiOperation(value = "新增拖车记录", notes = "新增拖车记录")
    @ApiImplicitParam(name = "towingRecordForm", value = "拖车记录表单", required = true, paramType = "body", dataType = "TowingRecordForm")
    @RequestMapping(value = "/detail/towinghis", method = RequestMethod.POST)
    public Object addOrUpdateTowingHis(@AuthenticationPrincipal User logedUser, @RequestBody TowingRecordForm towingRecordForm) {
        Optional<User> userOptional = Optional.ofNullable(logedUser);
        if (userOptional.isPresent()) {
            try {
                TowingHisBO towingHisBO = BeanCopierUtil.convert(towingRecordForm, TowingHisBO.class);
                return BizResult.create(null, overdueService.addOrUpdateTowingHis(logedUser.getStaffId(), towingHisBO), ErrorCodeEnum.SUCCESS.getErrCode(), ErrorCodeEnum.SUCCESS.getErrMsg());
            } catch (Exception e) {
                log.error("ERROR IN addTowingRecord", e);
                return BizResult.create(ErrorCodeEnum.SYS_ERROR.getErrCode(), e.getMessage());
            }
        } else {
            return BizResult.create(ErrorCodeEnum.NOT_LOGIN.getErrCode(), ErrorCodeEnum.NOT_LOGIN.getErrMsg());
        }
    }

    /**
     * 新增法院诉讼记录
     *
     * @param logedUser
     * @param lawsuitHisForm
     * @return
     */
    @ApiOperation(value = "新增法院诉讼记录", notes = "新增法院诉讼记录")
    @ApiImplicitParam(name = "lawsuitHisForm", value = "法院诉讼记表单", required = true, paramType = "body", dataType = "LawsuitHisForm")
    @RequestMapping(value = "/detail/lawsuit", method = RequestMethod.POST)
    public Object addLawsuitHis(@AuthenticationPrincipal User logedUser, @RequestBody LawsuitHisForm lawsuitHisForm) {
        Optional<User> userOptional = Optional.ofNullable(logedUser);
        if (userOptional.isPresent()) {
            try {
                LawsuitHisBO lawsuitHisBO = BeanCopierUtil.convert(lawsuitHisForm, LawsuitHisBO.class);
                return BizResult.create(null, overdueService.addLawsuitHis(logedUser.getStaffId(), lawsuitHisBO), ErrorCodeEnum.SUCCESS.getErrCode(), ErrorCodeEnum.SUCCESS.getErrMsg());
            } catch (Exception e) {
                log.error("ERROR IN addLawsuitHis", e);
                return BizResult.create(ErrorCodeEnum.SYS_ERROR.getErrCode(), e.getMessage());
            }
        } else {
            return BizResult.create(ErrorCodeEnum.NOT_LOGIN.getErrCode(), ErrorCodeEnum.NOT_LOGIN.getErrMsg());
        }
    }

    /**
     * 分配外勤（上门催收）
     *
     * @param logedUser
     * @param distributeCollectForm
     * @return
     */
    @ApiOperation(value = "分配外勤（上门催收）", notes = "分配外勤（上门催收）")
    @ApiImplicitParam(name = "distributeCollectForm", value = "外勤分配信息", required = true, paramType = "body", dataType = "DistributeCollectForm")
    @RequestMapping(value = "/detail/distribute/visit", method = RequestMethod.POST)
    public Object distributeCollectTask(@AuthenticationPrincipal User logedUser, @RequestBody DistributeCollectForm distributeCollectForm) {
        Optional<User> userOptional = Optional.ofNullable(logedUser);
        if (userOptional.isPresent()) {
            try {
                DistributeCollectBO distributeCollectBO = BeanCopierUtil.convert(distributeCollectForm, DistributeCollectBO.class);
                return BizResult.create(null, overdueService.distributeCollectTask(logedUser.getStaffId(), distributeCollectBO), ErrorCodeEnum.SUCCESS.getErrCode(), ErrorCodeEnum.SUCCESS.getErrMsg());
            } catch (Exception e) {
                log.error("ERROR IN distributeCollectTask", e);
                return BizResult.create(ErrorCodeEnum.SYS_ERROR.getErrCode(), e.getMessage());
            }
        } else {
            return BizResult.create(ErrorCodeEnum.NOT_LOGIN.getErrCode(), ErrorCodeEnum.NOT_LOGIN.getErrMsg());
        }
    }

    /**
     * 获取外勤小组列表
     *
     * @return
     */
    @ApiOperation(value = "获取外勤小组列表", notes = "获取外勤小组列表")
    @RequestMapping(value = "/outWorkerDept/list", method = RequestMethod.GET)
    public Object getOutWorkerDeptId() {
        try {
            DataDictQuery dataDictQuery = new DataDictQuery();
            dataDictQuery.createCriteria().andDataGroupEqualTo(DepartmentEnum.OUT_WORKER_GROUP);
            BizResult result = BizResult.create(overdueService.getDepartmentListInDataDict(dataDictQuery), true, ErrorCodeEnum.SUCCESS.getErrCode(), ErrorCodeEnum.SUCCESS.getErrMsg());
            result.setTotalCount(((List) result.getData()).size());
            return result;
        } catch (Exception e) {
            log.error("ERROR IN getOutWorkerDeptId", e);
            return BizResult.create(ErrorCodeEnum.SYS_ERROR.getErrCode(), e.getMessage());
        }
    }

    /**
     * 获取资产保全部下所有的员工
     * 电催人员
     * @return
     */
    @ApiOperation(value = "获取资产保全部下所有的员工", notes = "获取资产保全部下所有的员工")
    @RequestMapping(value = "/assetProtect/staff/list", method = RequestMethod.GET)
    public Object getAssetProtectStaffs(@AuthenticationPrincipal User logedUser) {
        Optional<User> userOptional = Optional.ofNullable(logedUser);
        if (userOptional.isPresent()) {
            try {
                BizResult result = new BizResult();
                for (DataDictDTO dataDictDTO : dataDictService.getGroupDataList(DepartmentEnum.DEPT_ID_GROUP, logedUser.getCompanyNo())) {
                    if (dataDictDTO.getName().equals(DepartmentEnum.ASSET_PROTECT_DEPT)) {
                        result = BizResult.create(staffRoleService.getStaffByDeptId(Long.parseLong(dataDictDTO.getCode())), true, ErrorCodeEnum.SUCCESS.getErrCode(), ErrorCodeEnum.SUCCESS.getErrMsg());
                        result.setTotalCount(((List) result.getData()).size());
                    }
                }
                return result;
            } catch (Exception e) {
                log.error("ERROR IN getAssetProtectStaffs", e);
                return BizResult.create(ErrorCodeEnum.SYS_ERROR.getErrCode(), e.getMessage());
            }
        } else {
            return BizResult.create(ErrorCodeEnum.NOT_LOGIN.getErrCode(), ErrorCodeEnum.NOT_LOGIN.getErrMsg());
        }
    }

    /**
     * 获取资产保全部下所有的外勤人员
     *
     * @return
     */
    @ApiOperation(value = "获取资产保全部下所有的外勤人员", notes = "获取资产保全部下所有的外勤人员")
    @RequestMapping(value = "/assetProtect/outWorker/list", method = RequestMethod.GET)
    public Object getAssetProtectOutWorkers() {
        try {
            //使用外勤人员角色编码获取对应的所有员工
            BizResult result = BizResult.create(staffRoleService.selectStaffByRole(DepartmentEnum.ASSETS_OUT_WORKER_ROLE_CODE), true, ErrorCodeEnum.SUCCESS.getErrCode(), ErrorCodeEnum.SUCCESS.getErrMsg());
            result.setTotalCount(((List) result.getData()).size());
            return result;
        } catch (Exception e) {
            log.error("ERROR IN getAssetProtectOutWorkers", e);
            return BizResult.create(ErrorCodeEnum.SYS_ERROR.getErrCode(), e.getMessage());
        }
    }

    /**
     * 获取订单对应的上门催收处理人（上门外勤）
     * @param orderNo
     * @return
     */
    @ApiOperation(value = "获取订单对应的上门催收处理人", notes = "获取订单对应的上门催收处理人")
    @RequestMapping(value = "/collect/outWorker/list", method = RequestMethod.GET)
    public Object getOrderCollectOutWorkers(String orderNo) {
        try {
            BizResult result = BizResult.create(overdueService.getOrderCollectOutWorkers(orderNo), true, ErrorCodeEnum.SUCCESS.getErrCode(), ErrorCodeEnum.SUCCESS.getErrMsg());
            result.setTotalCount(((List)result.getData()).size());
            return result;
        } catch (Exception e) {
            log.error("ERROR IN getAssetProtectOutWorkers", e);
            return BizResult.create(ErrorCodeEnum.SYS_ERROR.getErrCode(), e.getMessage());
        }
    }

}
